package modules.evaluator;

import java.io.BufferedReader;
import java.io.FileReader;

import miscellaneous.SequenceFileWriter;

public class MultiSpecEvaluator {
	public void qualityEvaluator(String path, String output, String software, String clusterFileName) {
		int[] familySize = {10, 44, 6, 44, 78, 12, 899, 56, 9, 22, 46, 8, 44, 38, 31, 32, 55, 12, 77, 38};

		try {
			SequenceFileWriter.writeAndAppendLine(path, output, "Quality results for " + software);

			int totalClusterSize = 0;
			int currentCluster = 0;
			BufferedReader bufferedreader;
			String str;

			bufferedreader = new BufferedReader(new FileReader(path + clusterFileName));
			while ((str = bufferedreader.readLine()) != null) 
				totalClusterSize++;
			bufferedreader.close();

			double[][] fMatrix = new double[familySize.length][totalClusterSize];
			int[][] clusterFamilyCounter = new int[familySize.length][totalClusterSize];

			bufferedreader = new BufferedReader(new FileReader(path + clusterFileName));
			while ((str = bufferedreader.readLine()) != null) { 
				for(int i = 0; i < familySize.length; i++) 
					clusterFamilyCounter[i][currentCluster] = 0;
				String[] strArr = str.split("\t");
				for(int i = 0; i < strArr.length; i++) 
					clusterFamilyCounter[Integer.parseInt(strArr[i])][currentCluster]++;
				for (int i = 0; i < familySize.length; i++) {
					double precision = (double)clusterFamilyCounter[i][currentCluster]/strArr.length;
					double recall = (double)clusterFamilyCounter[i][currentCluster]/(double)familySize[i];
					double fijValue = 0;
					if(precision != 0 || recall != 0)
						fijValue = ((double)2 * precision * recall)/(double)(precision + recall);
					fMatrix[i][currentCluster] = fijValue;
				}
				currentCluster++;
			}
			double[] fiArray = new double[familySize.length];
			double fScore = (double)0;

			for(int i = 0; i < familySize.length; i++) {
				double score = (double)0;
				for(int j = 0; j < totalClusterSize; j++) {
					fScore = fScore + (double)((double)clusterFamilyCounter[i][j] * fMatrix[i][j]/(double)1561);
					score = score + (double)((double)clusterFamilyCounter[i][j] * fMatrix[i][j]/familySize[i]);
				}
				fiArray[i] = score;
			}

			for(int i = 0; i < familySize.length; i++) 
				SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(fiArray[i]));
			SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(fScore));
			SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(totalClusterSize));
		} catch (Exception e) {
			System.out.println("ClusterQualityEvaluator Failed : " + e.getMessage()); 
			System.exit(-1);
		}
	}
	
	public void qualityEvaluatorWithoutKinase(String path, String output, String software, String clusterFileName) {
		int[] familySize = {10, 44, 6, 44, 78, 12, 56, 9, 22, 46, 8, 44, 38, 31, 32, 55, 12, 77, 38};

		try {
			SequenceFileWriter.writeAndAppendLine(path, output, "Kinaseless Quality results for " + software);

			int totalClusterSize = 0;
			int currentCluster = 0;
			BufferedReader bufferedreader;
			String str;

			bufferedreader = new BufferedReader(new FileReader(path + clusterFileName));
			while ((str = bufferedreader.readLine()) != null) 
				totalClusterSize++;
			bufferedreader.close();

			double[][] fMatrix = new double[familySize.length][totalClusterSize];
			int[][] clusterFamilyCounter = new int[familySize.length][totalClusterSize];

			bufferedreader = new BufferedReader(new FileReader(path + clusterFileName));
			while ((str = bufferedreader.readLine()) != null) { 
				for(int i = 0; i < familySize.length; i++) 
					clusterFamilyCounter[i][currentCluster] = 0;
				String[] strArr = str.split("\t");
				for(int i = 0; i < strArr.length; i++) 
					clusterFamilyCounter[Integer.parseInt(strArr[i])][currentCluster]++;
				for (int i = 0; i < familySize.length; i++) {
					double precision = (double)clusterFamilyCounter[i][currentCluster]/strArr.length;
					double recall = (double)clusterFamilyCounter[i][currentCluster]/(double)familySize[i];
					double fijValue = 0;
					if(precision != 0 || recall != 0)
						fijValue = ((double)2 * precision * recall)/(double)(precision + recall);
					fMatrix[i][currentCluster] = fijValue;
				}
				currentCluster++;
			}
			double[] fiArray = new double[familySize.length];
			double fScore = (double)0;

			for(int i = 0; i < familySize.length; i++) {
				double score = (double)0;
				for(int j = 0; j < totalClusterSize; j++) {
					fScore = fScore + (double)((double)clusterFamilyCounter[i][j] * fMatrix[i][j]/(double)662);
					score = score + (double)((double)clusterFamilyCounter[i][j] * fMatrix[i][j]/familySize[i]);
				}
				fiArray[i] = score;
			}

			for(int i = 0; i < familySize.length; i++) 
				SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(fiArray[i]));
			SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(fScore));
			SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(totalClusterSize));
		} catch (Exception e) {
			System.out.println("ClusterQualityEvaluator Failed : " + e.getMessage()); 
			System.exit(-1);
		}
	}
	
	public void precisionEvaluator(String path, String output, String software, String clusterFileName) {
		int[] familySize = {10, 44, 6, 44, 78, 12, 899, 56, 9, 22, 46, 8, 44, 38, 31, 32, 55, 12, 77, 38};

		try {
			SequenceFileWriter.writeAndAppendLine(path, output, "Precision results for " + software);

			int totalClusterSize = 0;
			int currentCluster = 0;
			BufferedReader bufferedreader;
			String str;

			bufferedreader = new BufferedReader(new FileReader(path + clusterFileName));
			while ((str = bufferedreader.readLine()) != null) 
				totalClusterSize++;
			bufferedreader.close();

			double[][] fMatrix = new double[familySize.length][totalClusterSize];
			int[][] clusterFamilyCounter = new int[familySize.length][totalClusterSize];

			bufferedreader = new BufferedReader(new FileReader(path + clusterFileName));
			while ((str = bufferedreader.readLine()) != null) { 
				for(int i = 0; i < familySize.length; i++) 
					clusterFamilyCounter[i][currentCluster] = 0;
				String[] strArr = str.split("\t");
				for(int i = 0; i < strArr.length; i++) 
					clusterFamilyCounter[Integer.parseInt(strArr[i])][currentCluster]++;
				for (int i = 0; i < familySize.length; i++) {
					double precision = (double)clusterFamilyCounter[i][currentCluster]/strArr.length;
					fMatrix[i][currentCluster] = precision;
				}
				currentCluster++;
			}
			double[] fiArray = new double[familySize.length];
			double fScore = (double)0;

			for(int i = 0; i < familySize.length; i++) {
				double score = (double)0;
				for(int j = 0; j < totalClusterSize; j++) {
					fScore = fScore + (double)((double)clusterFamilyCounter[i][j] * fMatrix[i][j]/(double)1561);
					score = score + (double)((double)clusterFamilyCounter[i][j] * fMatrix[i][j]/familySize[i]);
				}
				fiArray[i] = score;
			}

			for(int i = 0; i < familySize.length; i++) 
				SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(fiArray[i]));
			SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(fScore));
			SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(totalClusterSize));
		} catch (Exception e) {
			System.out.println("ClusterQualityEvaluator Failed : " + e.getMessage()); 
			System.exit(-1);
		}
	}
	
	public void precisionEvaluatorWithoutKinase(String path, String output, String software, String clusterFileName) {
		int[] familySize = {10, 44, 6, 44, 78, 12, 56, 9, 22, 46, 8, 44, 38, 31, 32, 55, 12, 77, 38};

		try {
			SequenceFileWriter.writeAndAppendLine(path, output, "KinaseLessPrecision results for " + software);

			int totalClusterSize = 0;
			int currentCluster = 0;
			BufferedReader bufferedreader;
			String str;

			bufferedreader = new BufferedReader(new FileReader(path + clusterFileName));
			while ((str = bufferedreader.readLine()) != null) 
				totalClusterSize++;
			bufferedreader.close();

			double[][] fMatrix = new double[familySize.length][totalClusterSize];
			int[][] clusterFamilyCounter = new int[familySize.length][totalClusterSize];

			bufferedreader = new BufferedReader(new FileReader(path + clusterFileName));
			while ((str = bufferedreader.readLine()) != null) { 
				for(int i = 0; i < familySize.length; i++) 
					clusterFamilyCounter[i][currentCluster] = 0;
				String[] strArr = str.split("\t");
				for(int i = 0; i < strArr.length; i++) 
					clusterFamilyCounter[Integer.parseInt(strArr[i])][currentCluster]++;
				for (int i = 0; i < familySize.length; i++) {
					double precision = (double)clusterFamilyCounter[i][currentCluster]/strArr.length;
					fMatrix[i][currentCluster] = precision;
				}
				currentCluster++;
			}
			double[] fiArray = new double[familySize.length];
			double fScore = (double)0;

			for(int i = 0; i < familySize.length; i++) {
				double score = (double)0;
				for(int j = 0; j < totalClusterSize; j++) {
					fScore = fScore + (double)((double)clusterFamilyCounter[i][j] * fMatrix[i][j]/(double)662);
					score = score + (double)((double)clusterFamilyCounter[i][j] * fMatrix[i][j]/familySize[i]);
				}
				fiArray[i] = score;
			}

			for(int i = 0; i < familySize.length; i++) 
				SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(fiArray[i]));
			SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(fScore));
			SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(totalClusterSize));
		} catch (Exception e) {
			System.out.println("ClusterQualityEvaluator Failed : " + e.getMessage()); 
			System.exit(-1);
		}
	}
	
	public void recallEvaluator(String path, String output, String software, String clusterFileName) {
		int[] familySize = {10, 44, 6, 44, 78, 12, 899, 56, 9, 22, 46, 8, 44, 38, 31, 32, 55, 12, 77, 38};

		try {
			SequenceFileWriter.writeAndAppendLine(path, output, "Recall results for " + software);

			int totalClusterSize = 0;
			int currentCluster = 0;
			BufferedReader bufferedreader;
			String str;

			bufferedreader = new BufferedReader(new FileReader(path + clusterFileName));
			while ((str = bufferedreader.readLine()) != null) 
				totalClusterSize++;
			bufferedreader.close();

			double[][] fMatrix = new double[familySize.length][totalClusterSize];
			int[][] clusterFamilyCounter = new int[familySize.length][totalClusterSize];

			bufferedreader = new BufferedReader(new FileReader(path + clusterFileName));
			while ((str = bufferedreader.readLine()) != null) { 
				for(int i = 0; i < familySize.length; i++) 
					clusterFamilyCounter[i][currentCluster] = 0;
				String[] strArr = str.split("\t");
				for(int i = 0; i < strArr.length; i++) 
					clusterFamilyCounter[Integer.parseInt(strArr[i])][currentCluster]++;
				for (int i = 0; i < familySize.length; i++) {
					double recall = (double)clusterFamilyCounter[i][currentCluster]/(double)familySize[i];
					fMatrix[i][currentCluster] = recall;
				}
				currentCluster++;
			}
			double[] fiArray = new double[familySize.length];
			double fScore = (double)0;

			for(int i = 0; i < familySize.length; i++) {
				double score = (double)0;
				for(int j = 0; j < totalClusterSize; j++) {
					fScore = fScore + (double)((double)clusterFamilyCounter[i][j] * fMatrix[i][j]/(double)1561);
					score = score + (double)((double)clusterFamilyCounter[i][j] * fMatrix[i][j]/familySize[i]);
				}
				fiArray[i] = score;
			}

			for(int i = 0; i < familySize.length; i++) 
				SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(fiArray[i]));
			SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(fScore));
			SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(totalClusterSize));
		} catch (Exception e) {
			System.out.println("ClusterQualityEvaluator Failed : " + e.getMessage()); 
			System.exit(-1);
		}
	}
	
	public void recallEvaluatorWithoutKinase(String path, String output, String software, String clusterFileName) {
		int[] familySize = {10, 44, 6, 44, 78, 12, 56, 9, 22, 46, 8, 44, 38, 31, 32, 55, 12, 77, 38};

		try {
			SequenceFileWriter.writeAndAppendLine(path, output, "Kinaseless Recall results for " + software);

			int totalClusterSize = 0;
			int currentCluster = 0;
			BufferedReader bufferedreader;
			String str;

			bufferedreader = new BufferedReader(new FileReader(path + clusterFileName));
			while ((str = bufferedreader.readLine()) != null) 
				totalClusterSize++;
			bufferedreader.close();

			double[][] fMatrix = new double[familySize.length][totalClusterSize];
			int[][] clusterFamilyCounter = new int[familySize.length][totalClusterSize];

			bufferedreader = new BufferedReader(new FileReader(path + clusterFileName));
			while ((str = bufferedreader.readLine()) != null) { 
				for(int i = 0; i < familySize.length; i++) 
					clusterFamilyCounter[i][currentCluster] = 0;
				String[] strArr = str.split("\t");
				for(int i = 0; i < strArr.length; i++) 
					clusterFamilyCounter[Integer.parseInt(strArr[i])][currentCluster]++;
				for (int i = 0; i < familySize.length; i++) {
					double recall = (double)clusterFamilyCounter[i][currentCluster]/(double)familySize[i];
					fMatrix[i][currentCluster] = recall;
				}
				currentCluster++;
			}
			double[] fiArray = new double[familySize.length];
			double fScore = (double)0;

			for(int i = 0; i < familySize.length; i++) {
				double score = (double)0;
				for(int j = 0; j < totalClusterSize; j++) {
					fScore = fScore + (double)((double)clusterFamilyCounter[i][j] * fMatrix[i][j]/(double)662);
					score = score + (double)((double)clusterFamilyCounter[i][j] * fMatrix[i][j]/familySize[i]);
				}
				fiArray[i] = score;
			}

			for(int i = 0; i < familySize.length; i++) 
				SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(fiArray[i]));
			SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(fScore));
			SequenceFileWriter.writeAndAppendLine(path, output, String.valueOf(totalClusterSize));
		} catch (Exception e) {
			System.out.println("ClusterQualityEvaluator Failed : " + e.getMessage()); 
			System.exit(-1);
		}
	}
}
